
from flask import Blueprint, request, jsonify, g
from backend.services.share_189_service import Share189Service
from backend.utils.response import success_response, error_response, validation_error_response
from backend.utils.auth import token_required
from backend.models import db
from typing import Dict, Any
import logging

logger = logging.getLogger(__name__)

# 创建189云盘分享码蓝图
share_189_bp = Blueprint('share_189', __name__, url_prefix='/api/share189')


# 移除自定义的create_api_response函数，使用统一的响应函数


@share_189_bp.route('/add', methods=['POST'])
@token_required
def add_share_codes():
    """批量添加分享码
    REF: API-SHARE189-001
    """
    try:
        data = request.get_json()
        if not data or 'shareCodes' not in data:
            return validation_error_response("请求参数错误：缺少shareCodes字段")
        
        share_codes = data['shareCodes']
        if not isinstance(share_codes, list) or len(share_codes) == 0:
            return validation_error_response("shareCodes必须是非空数组")
        
        # 转换为Service层期望的格式
        share_items = []
        for code in share_codes:
            if isinstance(code, str):
                # 简单字符串格式
                share_items.append({
                    'shareCode': code.strip(),
                    'accessCode': '',
                    'description': ''
                })
            elif isinstance(code, dict):
                # 对象格式
                share_items.append({
                    'shareCode': code.get('shareCode', '').strip(),
                    'accessCode': code.get('accessCode', '').strip(),
                    'description': code.get('description', '').strip()
                })
            else:
                return validation_error_response("shareCodes数组中的元素必须是字符串或对象")
        
        # 从认证信息获取用户ID
        owner_id = g.current_user.id
        
        result = Share189Service.add_share_codes(share_items, owner_id)
        
        return success_response(
            data=result,
            message='批量添加分享码完成'
        )
        
    except Exception as e:
        logger.error(f"批量添加分享码失败: {str(e)}")
        return error_response(f"批量添加分享码失败: {str(e)}", 500)


@share_189_bp.route('/list', methods=['GET'])
@token_required
def get_share_list():
    """获取分享码列表
    REF: API-SHARE189-002
    """
    try:
        # 获取查询参数
        status = request.args.get('status', type=int)
        keyword = request.args.get('keyword', '')
        page = request.args.get('page', 1, type=int)
        page_size = request.args.get('pageSize', 20, type=int)
        # 从认证信息获取用户ID，也支持通过参数指定
        # 如果明确传递了空的ownerId参数，则不进行owner过滤
        owner_id_param = request.args.get('ownerId')
        if owner_id_param is not None:
            # 如果传递了ownerId参数
            if owner_id_param == '':
                # 空字符串表示不进行owner过滤
                owner_id = None
            else:
                # 转换为整数
                owner_id = int(owner_id_param)
        else:
            # 没有传递ownerId参数，使用当前用户ID
            owner_id = g.current_user.id
        
        # 参数验证
        if page < 1:
            page = 1
        if page_size < 1 or page_size > 100:
            page_size = 20
        
        result = Share189Service.get_share_list(status, keyword, page, page_size, owner_id)
        
        return success_response(
            data=result,
            message='获取分享码列表成功'
        )
        
    except Exception as e:
        logger.error(f"获取分享码列表失败: {str(e)}")
        return error_response(f"获取分享码列表失败: {str(e)}", 500)


@share_189_bp.route('/preview-code', methods=['POST'])
@token_required
def preview_share_code():
    """预览分享码内容（不保存到数据库）
    REF: API-SHARE189-003
    """
    try:
        data = request.get_json()
        if not data or 'shareCode' not in data:
            return validation_error_response("请求参数错误：缺少shareCode字段")
        
        share_code = data['shareCode'].strip()
        access_code = data.get('accessCode', '').strip()
        depth = data.get('depth', 3)
        
        if not share_code:
            return validation_error_response("分享码不能为空")
        
        result = Share189Service.preview_share_code(share_code, access_code, depth)
        
        if result.get('success'):
            return success_response(
                data=result,
                message='预览分享码成功'
            )
        else:
            return error_response(result.get('message', '预览失败'), 400)
        
    except Exception as e:
        logger.error(f"预览分享码失败: {str(e)}")
        return error_response(f"预览分享码失败: {str(e)}", 500)


@share_189_bp.route('/<int:share_id>/preview', methods=['GET'])
@token_required
def get_file_tree_preview(share_id):
    """获取已解析分享码的文件树预览
    REF: API-SHARE189-004
    """
    try:
        max_items = request.args.get('maxItems', 50, type=int)
        # 从认证信息获取用户ID，也支持通过参数指定
        owner_id = request.args.get('ownerId', type=int) or g.current_user.id
        
        if max_items < 1 or max_items > 1000:
            max_items = 50
        
        result = Share189Service.get_file_tree_preview(share_id, max_items, owner_id)
        
        if result is None:
            return error_response("分享码不存在或未解析", 404)
        
        return success_response(
            data=result,
            message='获取文件树预览成功'
        )
        
    except Exception as e:
        logger.error(f"获取文件树预览失败: {str(e)}")
        return error_response(f"获取文件树预览失败: {str(e)}", 500)


@share_189_bp.route('/<int:share_id>', methods=['GET'])
@token_required
def get_share_detail(share_id):
    """获取分享码详情
    REF: API-SHARE189-005
    """
    try:
        # 从认证信息获取用户ID，也支持通过参数指定
        # 如果明确传递了空的ownerId参数，则不进行owner过滤
        owner_id_param = request.args.get('ownerId')
        if owner_id_param is not None:
            # 如果传递了ownerId参数
            if owner_id_param == '':
                # 空字符串表示不进行owner过滤
                owner_id = None
            else:
                # 转换为整数
                owner_id = int(owner_id_param)
        else:
            # 没有传递ownerId参数，使用当前用户ID
            owner_id = g.current_user.id
        
        result = Share189Service.get_share_detail(share_id, owner_id)
        
        if result is None:
            return error_response("分享码不存在", 404)
        
        # 将fileTreeJson字段映射为前端期望的fileTree字段
        if result and 'fileTreeJson' in result:
            file_tree_data = result.pop('fileTreeJson')
            if file_tree_data and isinstance(file_tree_data, dict):
                # 提取fileInfo作为fileTree
                result['fileTree'] = file_tree_data.get('fileInfo', [])
        
        return success_response(
            data=result,
            message='获取分享码详情成功'
        )
        
    except Exception as e:
        logger.error(f"获取分享码详情失败: {str(e)}")
        return error_response(f"获取分享码详情失败: {str(e)}", 500)


@share_189_bp.route('/<int:share_id>/parse', methods=['POST'])
@token_required
def parse_share_code(share_id):
    """触发解析分享码
    REF: API-SHARE189-006
    """
    try:
        data = request.get_json() or {}
        force = data.get('force', False)
        depth = data.get('depth', 3)
        # 从认证信息获取用户ID
        owner_id = g.current_user.id
        
        # 参数验证
        if depth < 1 or depth > 10:
            depth = 3
        
        result = Share189Service.parse_share_code(share_id, force, depth, owner_id)
        
        return success_response(
            data=result,
            message='解析分享码完成'
        )
        
    except Exception as e:
        logger.error(f"解析分享码失败: {str(e)}")
        return error_response(f"解析分享码失败: {str(e)}", 500)


@share_189_bp.route('/<int:share_id>/import', methods=['POST'])
@token_required
def import_files(share_id):
    """导入文件到网盘
    REF: API-SHARE189-007
    """
    try:
        data = request.get_json() or {}
        
        # targetFolderId可选，默认为None（根目录）
        target_folder_id = data.get('targetFolderId')
        conflict_strategy = data.get('conflictStrategy', 'rename')
        preserve_structure = data.get('preserveStructure', True)
        # 从认证信息获取用户ID
        owner_id = g.current_user.id
        
        # 参数验证
        if conflict_strategy not in ['rename', 'skip', 'overwrite']:
            conflict_strategy = 'rename'
        
        result = Share189Service.import_files(
            share_id, target_folder_id, conflict_strategy, preserve_structure, owner_id
        )
        
        return success_response(
            data=result,
            message='开始导入文件'
        )
        
    except Exception as e:
        logger.error(f"导入文件失败: {str(e)}")
        return error_response(f"导入文件失败: {str(e)}", 500)


@share_189_bp.route('/<int:share_id>', methods=['DELETE'])
@token_required
def delete_share_code(share_id):
    """删除分享码
    REF: API-SHARE189-009
    """
    try:
        # 从认证信息获取用户ID，也支持通过参数指定
        owner_id = request.args.get('ownerId', type=int) or g.current_user.id
        
        result = Share189Service.delete_share_code(share_id, owner_id)
        
        return success_response(
            data=result,
            message='删除分享码成功'
        )
        
    except Exception as e:
        logger.error(f"删除分享码失败: {str(e)}")
        return error_response(f"删除分享码失败: {str(e)}", 500)


@share_189_bp.route('/statistics', methods=['GET'])
@token_required
def get_statistics():
    """获取统计信息
    REF: API-SHARE189-008
    """
    try:
        # 从认证信息获取用户ID，也支持通过参数指定
        owner_id = request.args.get('ownerId', type=int) or g.current_user.id
        
        # 获取统计数据
        stats = Share189Service.get_statistics(owner_id)
        
        # 确保响应中包含测试所需的字段
        response_data = {
            'total': stats.get('total', 0),
            'success': stats.get('success', 0),
            'failed': stats.get('failed', 0),
            'pending': stats.get('pending', 0),
            'parseStatus': stats.get('parseStatus', {}),
            'importStatus': stats.get('importStatus', {}),
            'fileStatistics': stats.get('fileStatistics', {}),
            'totalShares': stats.get('totalShares', 0)
        }
        
        return success_response(
            data=response_data,
            message='获取统计信息成功'
        )
        
    except Exception as e:
        logger.error(f"获取统计信息失败: {str(e)}")
        return error_response(f"获取统计信息失败: {str(e)}", 500)


# 备注说明：
# 1. 解析分享码使用 share_utils.get_tianyi_share_data 方法
# 2. 解析结果数据结构参考 utils/share_189.json
# 3. 所有接口都支持owner_id参数进行权限控制
# 4. 统一的错误处理和日志记录
# 5. 符合API文档规范的请求/响应格式
